/*
Copyright (C) 2009-2010 Xanadu Development Team

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2
of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#include "../provider/DataProvider.h"
#include "../tools/PacketCreator.h"
#include "../client/PetsData.h"
#include "../client/PetData.h"
#include "Player.h"
#include "Pet.h"
#include "Map.h"
#include "../tools/Timer.h"
#include "../tools/Tools.h"
#include "../tools/Run.h"


class PetFullnessTimer : public Run{
private:
	Pet* pet;
	Player* player;
	int delay;
public:
	PetFullnessTimer(Player* player, Pet* pet, int delay):pet(pet), player(player), delay(delay){}
	void run(){
		pet->setFullness(pet->getFullness()-1);
		if(pet->getFullness() == 0){
			*pet->getTimer() = NULL;
			player->removePet(pet, true);
			pet->addCloseness(-20);
			pet->setFullness(5);
		}
		else{
			*pet->getTimer() = Timers::getInstance()->startTimer(delay, new PetFullnessTimer(player, pet, delay));
		}
		player->send(PacketCreator().updatePet(pet));
	}
};

int Pet::ids = 0x100;
int Pet::levels [30] = {1, 3, 6, 14, 31, 60, 108, 181, 287, 434, 632, 891, 1224, 1642, 2161, 2793, 3557, 4467, 5542, 6801, 8263, 9950, 11882, 14084, 16578, 19391, 22548, 26074, 30000, 0};

Pet::Pet(int id) :
lastTime(0),
petSlot(-1),
time(Tools::getTimeByDays(DataProvider::getInstance()->getPetLife(id))),
name(DataProvider::getInstance()->getItemName(id)),
level(1),
closeness(0),
fullness(100)
{
	timer = NULL;
	type = 5;
	amount = 1;
	slot = 0;
	lock = false;
	((Item*)this)->setID(id);
	((MapObject*)this)->setID(ids++);
}

Pet::~Pet() {
	// todo: remove timer
	stopTimer();
}

void Pet::setCloseness(short closeness, Player* player) {
	if(closeness > 30000) {
		closeness = 30000;
	}
	if(closeness < 0) {
		closeness = 0;
	}
	this->closeness = closeness;
	if(closeness >= levels[level-1] && level < 30) {
		while(closeness >= levels[level-1]) {
			level++;
			if(level == 30)
				break;
		}
		if(player != 0) {
			player->send(PacketCreator().showPlayerEffect(Player::Effects::PET_LEVEL_UP, petSlot));
			player->getMap()->send(PacketCreator().showEffect(player->getID(), Player::Effects::PET_LEVEL_UP, petSlot), player);
		}
	}
	if (player != 0) {
		player->send(PacketCreator().updatePet(this));
	}
}

void Pet::stopTimer(Player *player, int delay) {
	setFullness(getFullness() - 1);
	if (getFullness() == 0) {
		player->removePet(this, true);
		addCloseness(-20);
		setFullness(5);
	}
	else {
		//new Timer::Timer(std::tr1::bind(&Pet::stopTimer, this, player, delay), Timer::Id(Timer::Types::PetTimer, getItemID(), 0), player->getTimers(), Timer::Time::fromNow(5 * 60 * 1000 / getFullness()));
	}
	player->send(PacketCreator().updatePet(this));
}

void Pet::startTimer(Player* player){
	int petHunger = DataProvider::getInstance()->getPetHungry(getItemID());
	if( petHunger == 0 ) petHunger = 1;
	timer = Timers::getInstance()->startTimer(5*60*1000/petHunger, new PetFullnessTimer(player, this, 5*60*1000/petHunger));
}

void Pet::stopTimer(){
	if(timer != NULL)
		Timers::getInstance()->cancelTimer(timer);
}

Timer** Pet::getTimer()
{
	return &timer;
}